use super::position::*;

#[derive(Clone, Copy)]
pub struct PositionOffset {
    x: isize,
    y: isize,
}

fn offset_add(a: usize, b: isize, max: usize) -> usize {
    let is_positive = b >= 0;
    let abs_b = b.abs() as usize;

    let add_result = if is_positive {
        a.saturating_add(abs_b)
    } else {
        a.saturating_sub(abs_b)
    };

    if add_result > max {
        max
    } else {
        add_result
    }
}

impl PositionOffset {
    pub const fn new(x: isize, y: isize) -> Self {
        PositionOffset { x, y }
    }

    pub fn apply(&self, position: Position) -> Position {
        Position::new(
            position.size,
            offset_add(position.x(), self.x, position.size.width - 1),
            offset_add(position.y(), self.y, position.size.height - 1),
        )
    }

    pub const LEFT: PositionOffset = PositionOffset::new(-1, 0);
    pub const RIGHT: PositionOffset = PositionOffset::new(1, 0);
    pub const UP: PositionOffset = PositionOffset::new(0, -1);
    pub const DOWN: PositionOffset = PositionOffset::new(0, 1);
}


